﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using NSsh.Server.Services;
using Microsoft.Win32.SafeHandles;
using NSsh.Server.Utility;
using System.Diagnostics;
using System.ComponentModel;
using NSsh.Server.Types;
using System.Threading;
using System.IO;

namespace NSsh.Service.ExecutableLauncher
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var windowStation = SafeWindowStationHandle.CreateWindowStation(null))
            {
                Win32Native.SetProcessWindowStation(windowStation);

                using (var desktop = SafeDesktopHandle.CreateDesktop("default"))
                {
                    ProcessStartInfo processStartInfo = new ProcessStartInfo()
                    {
                        FileName = args[0],
                        Arguments = args[1],
                        RedirectStandardError = true,
                        RedirectStandardInput = true,
                        RedirectStandardOutput = true,
                        UseShellExecute = false
                    };

                    StartProcessAndRedirect(processStartInfo);
                }
            }
        }

        private static void StartProcessAndRedirect(ProcessStartInfo processStartInfo)
        {
            Process process = Process.Start(processStartInfo);

            ThreadPool.QueueUserWorkItem(delegate
            {
                Forward(Console.In, process.StandardInput);
            });

            ThreadPool.QueueUserWorkItem(delegate
            {

                Forward(process.StandardOutput, Console.Out);
            });

            ThreadPool.QueueUserWorkItem(delegate
            {
                Forward(process.StandardError, Console.Error);
            });

            process.WaitForExit();
        }

        private static void Forward(TextReader reader, TextWriter writer)
        {
            char[] buffer = new char[0x1000];

            while (true)
            {
                int bytesRead = reader.Read(buffer, 0, buffer.Length);

                if (bytesRead == 0)
                {
                    break;
                }

                writer.Write(buffer, 0, bytesRead);
            }
        }
    }
}
